<template>
  <div class="page">
    <div class="page-header">
      <h2>客户管理</h2>
      <div class="actions">
        <input type="file" ref="fileInput" style="display:none" @change="onImportFile" />
        <button class="btn btn-primary" @click="openAdd">新增</button>
        <button class="btn danger" :disabled="selectedIds.length===0" @click="confirmBatchDelete">批量删除</button>
        <button class="btn" @click="triggerImport">导入</button>
        <button class="btn" @click="handleExport">导出</button>
      </div>
    </div>

    <div class="search">
      <input v-model.trim="query.customerName" placeholder="客户名称(支持模糊)" class="ipt" @keyup.enter="onSearch" />
      <select v-model="query.status" class="ipt">
        <option value="">全部状态</option>
        <option :value="1">启用</option>
        <option :value="0">停用</option>
      </select>
      <button class="btn btn-primary" @click="onSearch">搜索</button>
      <button class="btn" @click="reset">重置</button>
    </div>

    <div class="table-wrap">
      <div class="table-tools">
        <label class="checkbox">
          <input type="checkbox" v-model="allChecked" @change="toggleAll"> 全选
        </label>
      </div>
      <table>
        <thead>
          <tr>
            <th style="width:44px;">选择</th>
            <th>ID</th>
            <th>客户编码</th>
            <th>客户名称</th>
            <th>联系人</th>
            <th>电话</th>
            <th>负责人</th>
            <th>开票地址</th>
            <th>收货地址</th>
            <th>销售订单数</th>
            <th>对账单数</th>
            <th>状态</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in list" :key="item.id">
            <td><input type="checkbox" :value="item.id" v-model="selectedIds"/></td>
            <td>{{ item.id }}</td>
            <td>{{ item.customer_code }}</td>
            <td>{{ item.customer_name }}</td>
            <td>{{ item.contact_name }}</td>
            <td>{{ item.phone }}</td>
            <td>{{ item.owner_name || '-' }}</td>
            <td class="ellipsis" :title="item.billing_address">{{ item.billing_address || '-' }}</td>
            <td class="ellipsis" :title="item.shipping_address">{{ item.shipping_address || '-' }}</td>
            <td>{{ item.salesOrderCount || 0 }}</td>
            <td>{{ item.reconciliationCount || 0 }}</td>
            <td>
              <span :class="['status', (item.status??form.status)===1?'on':'off']">{{ (item.status??form.status)===1?'启用':'停用' }}</span>
            </td>
            <td>
              <button class="btn sm" @click="openEdit(item)">编辑</button>
              <button class="btn sm danger" @click="remove(item)">删除</button>
            </td>
          </tr>
        </tbody>
      </table>
      <div class="pager">
        <button class="btn sm" :disabled="page.current===1" @click="go(page.current-1)">上一页</button>
        <span>{{ page.current }} / {{ totalPages }}</span>
        <button class="btn sm" :disabled="page.current===totalPages" @click="go(page.current+1)">下一页</button>
      </div>
    </div>

    <div v-if="showModal" class="modal" @click.self="close">
      <div class="dialog">
        <h3>{{ editing? '编辑客户' : '新增客户' }}</h3>
        <div class="form">
          <label>客户名称<input v-model="form.customer_name"/></label>
          <label>客户编码<input v-model="form.customer_code"/></label>
          <label>联系人<input v-model="form.contact_name"/></label>
          <label>电话<input v-model="form.phone"/></label>
          <label>邮箱<input v-model="form.email" type="email"/></label>
          <label>税号<input v-model="form.tax_no"/></label>
          <label>信用额度<input v-model.number="form.credit_limit" type="number" min="0"/></label>
          <label>账期天数<input v-model.number="form.payment_term_days" type="number" min="0"/></label>
          <label>开票地址<input v-model="form.billing_address"/></label>
          <label>收货地址<input v-model="form.shipping_address"/></label>
          <label>负责人
            <div class="select">
              <input class="ipt" placeholder="搜索员工" v-model="empKeyword" @input="loadEmployees(empKeyword)" />
              <select v-model.number="form.fu_id" class="ipt">
                <option :value="null">请选择负责人</option>
                <option v-for="e in employeeOptions" :key="e.id" :value="e.id">{{ e.employeeName }}</option>
              </select>
            </div>
          </label>
          <label>状态
            <select v-model.number="form.status">
              <option :value="1">启用</option>
              <option :value="0">停用</option>
            </select>
          </label>
        </div>
        <div class="dialog-actions">
          <button class="btn" @click="close">取消</button>
          <button class="btn btn-primary" @click="onSaveClick">保存</button>
        </div>
      </div>
    </div>
    <!-- 确认保存弹窗 -->
    <div v-if="showConfirm" class="modal" @click.self="showConfirm=false">
      <div class="confirm">
        <h3>确认保存</h3>
        <p>确定要保存当前客户信息吗？</p>
        <div class="confirm-actions">
          <button class="btn" @click="showConfirm=false">取消</button>
          <button class="btn btn-primary" @click="confirmSave">确认保存</button>
        </div>
      </div>
    </div>
    <!-- 成功提示弹窗 -->
    <div v-if="showSuccess" class="modal" @click.self="showSuccess=false">
      <div class="success">
        <h3>操作成功</h3>
        <p>{{ successMessage }}</p>
        <div class="confirm-actions">
          <button class="btn btn-primary" @click="showSuccess=false">知道了</button>
        </div>
      </div>
    </div>
  </div>
  
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { getCustomerPage, createCustomer, updateCustomer, deleteCustomer, deleteCustomerBatch, exportCustomers, importCustomers, getEmployeeOptions } from '@/api/sales'

const query = reactive({ customerName: '', status: '' })
const list = ref([])
const page = reactive({ current: 1, size: 10, total: 0 })
const totalPages = computed(() => Math.max(1, Math.ceil(page.total / page.size)))

async function load() {
  const res = await getCustomerPage({ pageNo: page.current, pageSize: page.size, customerName: query.customerName, status: query.status })
  // 后端返回结构：{records, total, current, size}
  if (Array.isArray(res)) {
    list.value = res
    page.total = res.length
  } else {
    const data = res.data ?? res
    list.value = data.records || data.list || []
    page.total = (data.total ?? 0) || list.value.length
    page.current = data.current ?? page.current
    page.size = data.size ?? page.size
  }
}

function onSearch(){
  page.current = 1
  load()
}
function reset(){
  query.customerName=''; query.status=''; page.current=1; load()
}

function go(p){ page.current=p; load() }

const showModal = ref(false)
const editing = ref(false)
const showConfirm = ref(false)
const showSuccess = ref(false)
const successMessage = ref('')
const form = reactive({ id:null, customer_name:'', customer_code:'', contact_name:'', phone:'', email:'', tax_no:'', credit_limit:null, payment_term_days:null, billing_address:'', shipping_address:'', status:1, fu_id:null })
const employeeOptions = ref([])
const empKeyword = ref('')
const selectedIds = ref([])
const allChecked = ref(false)

function openAdd(){
  editing.value=false;
  Object.assign(form,{ id:null, customer_name:'', customer_code:'', contact_name:'', phone:'', email:'', tax_no:'', credit_limit:null, payment_term_days:null, billing_address:'', shipping_address:'', status:1, fu_id:null });
  showModal.value=true;
  // 进入弹窗即加载所有在职员工
  loadEmployees('')
}
function openEdit(row){ editing.value=true; Object.assign(form, row); showModal.value=true; loadEmployees('') }
function close(){ showModal.value=false }

function onSaveClick(){
  showConfirm.value = true
}

async function confirmSave(){
  showConfirm.value = false
  if(!form.customer_name) return alert('请输入客户名称')
  const payload = mapFormToPayload(form)
  if(editing.value){ await updateCustomer(form.id, payload) } else { await createCustomer(payload) }
  close();
  successMessage.value = '客户信息已保存'
  showSuccess.value = true
  load()
}

// 将前端表单(下划线命名)映射为后端实体(驼峰命名)
function mapFormToPayload(fd){
  return {
    customerName: fd.customer_name,
    customerCode: fd.customer_code,
    contactName: fd.contact_name,
    phone: fd.phone,
    email: fd.email,
    taxNo: fd.tax_no,
    billingAddress: fd.billing_address,
    shippingAddress: fd.shipping_address,
    creditLimit: fd.credit_limit,
    paymentTermDays: fd.payment_term_days,
    status: fd.status,
    fuId: fd.fu_id,
    createName: localStorage.getItem('name') || localStorage.getItem('username') || 'admin'
  }
}

async function remove(row){
  const label = row.customer_name || row.customerName || row.id
  if(!confirm(`确认删除客户“${label}”吗？`)) return
  const res = await deleteCustomer(row.id)
  if (res === true || res?.success === true || res?.code === 0 || res?.code === 200) {
    successMessage.value = '删除成功'
    showSuccess.value = true
    load()
  } else {
    alert(res?.message || '该客户存在关联销售订单，无法删除')
  }
}

const fileInput = ref(null)
function triggerImport(){ fileInput.value && fileInput.value.click() }
async function onImportFile(e){
  const f = e.target.files?.[0]; if(!f) return
  await importCustomers(f)
  e.target.value='';
  load()
  successMessage.value = '导入成功'
  showSuccess.value = true
}

async function handleExport(){
  if(!confirm('确定导出当前筛选结果吗？')) return
  const res = await exportCustomers({ customerName: query.customerName, status: query.status })
  const blob = res instanceof Blob ? res : (res?.data instanceof Blob ? res.data : new Blob([res]))
  const url = window.URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = '客户列表.xlsx'
  a.click()
  window.URL.revokeObjectURL(url)
  successMessage.value = '导出成功'
  showSuccess.value = true
}

onMounted(() => { load(); loadEmployees('') })

async function loadEmployees(kw){
  const res = await getEmployeeOptions({ keyword: kw })
  employeeOptions.value = (res.data || res) // 兼容直接返回数组
}

function toggleAll(){
  if(allChecked.value){
    selectedIds.value = list.value.map(i=>i.id)
  } else {
    selectedIds.value = []
  }
}

async function confirmBatchDelete(){
  if(selectedIds.value.length===0) return
  if(!confirm(`确认删除选中的 ${selectedIds.value.length} 个客户吗？`)) return
  const res = await deleteCustomerBatch(selectedIds.value)
  if (res && (res.success === true || res.code === 0 || res.code === 200)) {
    successMessage.value = `删除成功（${res.deleted ?? selectedIds.value.length} 条）`
    showSuccess.value = true
    selectedIds.value=[]; allChecked.value=false; load()
  } else {
    alert(res?.message || '部分客户存在关联数据，无法删除')
  }
}
</script>

<style scoped>
.page{ display:flex; flex-direction:column; gap:16px; background:#f6f7f9; min-height:100%; padding:12px; }
.page-header{ display:flex; justify-content:space-between; align-items:center; background:#fff; padding:14px 16px; border-radius:10px; box-shadow:0 1px 2px rgba(0,0,0,.06); }
.actions{ display:flex; gap:10px; }
.search{ display:flex; gap:10px; background:#fff; padding:12px; border-radius:10px; box-shadow:0 1px 2px rgba(0,0,0,.06); }
.ipt{ padding:8px 10px; border:1px solid #dcdfe6; border-radius:6px; transition:border .2s, box-shadow .2s; background:#fff; }
.ipt:focus{ outline:none; border-color:#409eff; box-shadow:0 0 0 2px rgba(64,158,255,.15); }
.btn{ padding:8px 14px; border:1px solid #d0d0d0; background:#fff; border-radius:8px; cursor:pointer; transition:all .15s; }
.btn:hover{ box-shadow:0 2px 6px rgba(0,0,0,.08); transform:translateY(-1px); }
.btn.sm{ padding:6px 10px; border-radius:6px; }
.btn-primary{ background:#1677ff; color:#fff; border-color:#1677ff; }
.btn-primary:hover{ background:#3b8cff; }
.btn.danger{ background:#ff4d4f; color:#fff; border-color:#ff4d4f; }
.table-wrap{ background:#fff; border-radius:10px; padding:12px; box-shadow:0 1px 2px rgba(0,0,0,.06); }
table{ width:100%; border-collapse:collapse; }
th,td{ text-align:left; padding:12px 10px; border-bottom:1px solid #f0f0f0; font-size:14px }
thead th{ background:#fafafa; font-weight:600; color:#334155; }
.ellipsis{ max-width:260px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.status.on{ color:#10b981; font-weight:600; }
.status.off{ color:#ef4444; font-weight:600; }
.pager{ display:flex; gap:10px; justify-content:flex-end; padding:10px 0 }
.modal{ position:fixed; inset:0; background:rgba(0,0,0,.45); display:flex; align-items:center; justify-content:center; backdrop-filter: blur(2px); }
.dialog{ width:720px; background:#fff; border-radius:14px; padding:18px 20px; box-shadow:0 12px 30px rgba(0,0,0,.18); }
.dialog h3{ margin:0 0 12px; font-size:18px; color:#111827; }
.form{ display:grid; grid-template-columns:1fr 1fr; gap:16px 18px; }
.form label{ display:flex; flex-direction:column; gap:6px; color:#374151; font-size:13px; }
.form input,.form select{ padding:10px 12px; border:1px solid #dcdfe6; border-radius:8px; background:#fff; }
.form input:focus,.form select:focus{ outline:none; border-color:#409eff; box-shadow:0 0 0 2px rgba(64,158,255,.15); }
.select{ display:flex; gap:8px; align-items:center; }
.dialog-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:16px }
.confirm,.success{ width:380px; background:#fff; border-radius:12px; padding:18px; box-shadow:0 10px 24px rgba(0,0,0,.16); text-align:center }
.confirm h3,.success h3{ margin:0 0 8px; font-size:18px }
.confirm p,.success p{ color:#4b5563; margin:0 0 14px }
.confirm-actions{ display:flex; justify-content:flex-end; gap:10px }
</style>


